package controller

import (
	"errors"
	"fmt"
	"net/http"
	"one-api/common"
	"one-api/common/utils"
	"one-api/model"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
)

func GetChannelsList(c *gin.Context) {
	var params model.SearchChannelsParams
	if err := c.ShouldBindQuery(&params); err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}

	channels, err := model.GetChannelsList(&params)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data":    channels,
	})
}

func GetChannel(c *gin.Context) {
	id, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	channel, err := model.GetChannelById(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data":    channel,
	})
}

func AddChannel(c *gin.Context) {
	channel := model.Channel{}
	err := c.ShouldBindJSON(&channel)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	channel.CreatedTime = utils.GetTimestamp()
	keys := strings.Split(channel.Key, "\n")

	baseUrls := []string{}
	if channel.BaseURL != nil && *channel.BaseURL != "" {
		baseUrls = strings.Split(*channel.BaseURL, "\n")
	}
	channels := make([]model.Channel, 0, len(keys))
	for index, key := range keys {
		if key == "" {
			continue
		}
		localChannel := channel
		localChannel.Key = key
		if index > 0 {
			localChannel.Name = localChannel.Name + "_" + strconv.Itoa(index+1)
		}

		if len(baseUrls) > index && baseUrls[index] != "" {
			localChannel.BaseURL = &baseUrls[index]
		} else if len(baseUrls) > 0 {
			localChannel.BaseURL = &baseUrls[0]
		}

		channels = append(channels, localChannel)
	}
	err = model.BatchInsertChannels(channels)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
	})
}

func DeleteChannel(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	channel := model.Channel{Id: id}
	err := channel.Delete()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
	})
}

func DeleteChannelTag(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	err := model.DeleteChannelTag(id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
	})
}

func DeleteDisabledChannel(c *gin.Context) {
	rows, err := model.DeleteDisabledChannel()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data":    rows,
	})
}

func UpdateChannel(c *gin.Context) {
	channel := model.Channel{}
	err := c.ShouldBindJSON(&channel)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	if channel.Models == "" {
		err = channel.Update(false)
	} else {
		err = channel.Update(true)
	}
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data":    channel,
	})
}

func BatchUpdateChannelsAzureApi(c *gin.Context) {
	var params model.BatchChannelsParams
	err := c.ShouldBindJSON(&params)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}

	if params.Ids == nil || len(params.Ids) == 0 {
		common.APIRespondWithError(c, http.StatusOK, errors.New("ids不能为空"))
		return
	}
	var count int64
	count, err = model.BatchUpdateChannelsAzureApi(&params)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"data":    count,
		"success": true,
		"message": "更新成功",
	})
}

func ExportChannels(c *gin.Context) {
	channels, err := model.GetAllChannels()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": "Failed to get channels: " + err.Error(),
		})
		return
	}

	if len(channels) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": "No channels found",
		})
		return
	}

	// 设置响应头，提示下载文件
	c.Header("Content-Type", "application/json")
	c.Header("Content-Disposition", "attachment; filename=channels.json")
	
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Channels exported successfully",
		"data":    channels,
	})
}

type ImportChannelsRequest struct {
	Channels    []model.Channel `json:"channels" binding:"required"`
	Mode        string          `json:"mode"`        // skip, replace, merge (default: skip)
	ClearExist  bool            `json:"clear_exist"` // 是否先清空现有渠道
}

type ImportChannelsResponse struct {
	Total     int `json:"total"`     // 总数
	Success   int `json:"success"`   // 成功导入数
	Skipped   int `json:"skipped"`   // 跳过数
	Failed    int `json:"failed"`    // 失败数
	Errors    []string `json:"errors,omitempty"` // 错误信息
}

func ImportChannels(c *gin.Context) {
	var req ImportChannelsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": "Invalid request data: " + err.Error(),
		})
		return
	}

	if len(req.Channels) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": "No channels to import",
		})
		return
	}

	// 设置默认导入模式
	if req.Mode == "" {
		req.Mode = "skip"
	}

	// 验证导入模式
	if req.Mode != "skip" && req.Mode != "replace" && req.Mode != "merge" {
		c.JSON(http.StatusOK, gin.H{
			"success": false,
			"message": "Invalid import mode. Must be 'skip', 'replace', or 'merge'",
		})
		return
	}

	resp := ImportChannelsResponse{
		Total: len(req.Channels),
	}

	// 如果需要清空现有渠道
	if req.ClearExist {
		if err := model.DB.Exec("DELETE FROM channels").Error; err != nil {
			c.JSON(http.StatusOK, gin.H{
				"success": false,
				"message": "Failed to clear existing channels: " + err.Error(),
			})
			return
		}
	}

	// 获取现有渠道（用于重复检查）
	existingChannels := make(map[string]*model.Channel)
	if req.Mode != "merge" && !req.ClearExist {
		channels, err := model.GetAllChannels()
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"success": false,
				"message": "Failed to get existing channels: " + err.Error(),
			})
			return
		}
		
		for _, ch := range channels {
			// 使用名称+密钥作为唯一标识
			key := ch.Name + "|" + ch.Key
			existingChannels[key] = ch
		}
	}

	importChannels := make([]model.Channel, 0)
	
	for i, channel := range req.Channels {
		// 数据验证
		if channel.Name == "" {
			resp.Failed++
			resp.Errors = append(resp.Errors, fmt.Sprintf("Channel %d: name is required", i+1))
			continue
		}
		
		if channel.Key == "" {
			resp.Failed++
			resp.Errors = append(resp.Errors, fmt.Sprintf("Channel %d (%s): key is required", i+1, channel.Name))
			continue
		}

		// 设置创建时间
		if channel.CreatedTime == 0 {
			channel.CreatedTime = utils.GetTimestamp()
		}

		// 重置运行时数据
		channel.Id = 0 // 让数据库自动生成新ID
		channel.UsedQuota = 0
		channel.Balance = 0
		channel.BalanceUpdatedTime = 0
		channel.TestTime = 0
		channel.ResponseTime = 0

		// 检查重复
		channelKey := channel.Name + "|" + channel.Key
		if existing, exists := existingChannels[channelKey]; exists {
			switch req.Mode {
			case "skip":
				resp.Skipped++
				continue
			case "replace":
				// 删除现有渠道
				if err := existing.Delete(); err != nil {
					resp.Failed++
					resp.Errors = append(resp.Errors, fmt.Sprintf("Failed to delete existing channel %s: %s", channel.Name, err.Error()))
					continue
				}
			}
		}

		importChannels = append(importChannels, channel)
	}

	// 批量插入
	if len(importChannels) > 0 {
		if err := model.BatchInsertChannels(importChannels); err != nil {
			c.JSON(http.StatusOK, gin.H{
				"success": false,
				"message": "Failed to import channels: " + err.Error(),
			})
			return
		}
		resp.Success = len(importChannels)
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": fmt.Sprintf("Import completed: %d success, %d skipped, %d failed", 
			resp.Success, resp.Skipped, resp.Failed),
		"data": resp,
	})
}

func BatchDelModelChannels(c *gin.Context) {
	var params model.BatchChannelsParams
	err := c.ShouldBindJSON(&params)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}

	if params.Ids == nil || len(params.Ids) == 0 {
		common.APIRespondWithError(c, http.StatusOK, errors.New("ids不能为空"))
		return
	}

	var count int64
	count, err = model.BatchDelModelChannels(&params)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"data":    count,
		"success": true,
		"message": "更新成功",
	})
}

func BatchDeleteChannel(c *gin.Context) {
	var params model.BatchChannelsParams
	err := c.ShouldBindJSON(&params)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}

	if params.Ids == nil || len(params.Ids) == 0 {
		common.APIRespondWithError(c, http.StatusOK, errors.New("ids不能为空"))
		return
	}

	count, err := model.BatchDeleteChannel(params.Ids)
	if err != nil {
		common.APIRespondWithError(c, http.StatusOK, err)
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "",
		"data":    count,
	})
}
